home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
CC_C
/
0924.ZIP
/
TCED
< prev
Wrap
Text File
|
1988-01-10
|
30KB
|
942 lines
/* ------------- ASCII FILE SCREEN EDITOR ---------------
Requires MSDOS 3 and ANSI.SYS for cursor positioning.
Uses direct output to text mode video RAM at B800:0.
Reassigns stdin and stdout to avoid redirection.
Compile (under SMC) with options -F -D62 and -S1.
*/
#include <smio.h>
/* General definitions */
#define TCLR 2 /* keys to clear */
#define TABS 4 /* tab column pitch */
#define TWID 32 /* command width */
#define WIDTH 78 /* text line width */
#define TOPROW 3 /* display top line */
#define ENDROW 25 /* display end line */
#define QBSIZE 512 /* input buffer size */
#define RCHAR '\257' /* find/replace char */
#define EXFILE "EXTRACT" /* default file name */
/* Screen edit action key assignments - the settings
below are for the standard Amstrad PC1512 keyboard */
/* The function key settings are:
F1: Set for/leave external command, or
set search/replace string;
Shift F1: Quit;
F2: Insert buffer lines;
Shift F2: Delete lines to buffer;
F3: Append following line;
Shift F3: Break line at cursor;
F4: Beginning of line/top of page;
Shift F4: End of line;
Shift F5: Save edit;
F6: Move to next line;
Shift F6: Delete to end of line;
F7: Move to mark;
Shift F7: Set mark;
F8: Search/replace;
F9: Move to next word;
F10: Refresh screen.
*/
#define KLDEL 0x08 /* <-delete */
#define KRDEL 0x07 /* delete-> */
#define KESC 0x1B /* escape */
#define KEOF 0x4F00 /* end of file */
#define KTOP 0x4700 /* top of file */
#define KCUP 0x4800 /* cursor up */
#define KCDN 0x5000 /* cursor down */
#define KCLF 0x4B00 /* cursor left */
#define KCRT 0x4D00 /* cursor right */
#define KTAB 0x09 /* tab */
#define KRET 0x0D /* return */
#define KSCUP 0x4900 /* screen up */
#define KSCDN 0x5100 /* screen down */
#define KINS 0x5200 /* insert toggle */
#define KQAC 0x3E00 /* Q action */
#define KTLIN 0x3B00 /* command key */
#define KCONC 0x3D00 /* join lines */
#define KBDEL 0x5500 /* delete lines */
#define KBRES 0x3C00 /* restore lines */
#define KRFSH 0x4400 /* screen reset */
#define KCEOL 0x5700 /* cursor eol */
#define KDEOL 0x5900 /* delete eol */
#define KTWRD 0x4300 /* tab to word */
#define KMARK 0x5A00 /* set mark */
#define KGOMK 0x4100 /* go to mark */
#define KSRCH 0x4200 /* find/alter */
#define KQUIT 0x5400 /* quit edit */
#define KSAVE 0x5800 /* save edit */
#define KF3 0x5600 /* line break */
#define KF6 0x4000 /* next line */
/* Structure typedefs */
typedef struct { char *qnx, *qnd; int qfd; char qbb [QBSIZE]; } qbuf;
typedef struct mbk { struct mbk *lptr, *rptr; unsigned size; } mtag;
/* Global data */
mtag bfend[2], bfstt[2], base, *sline, *eline,
*bfe = bfend, *bfs = bfstt, *last = NULL,
*mline = NULL, *sdel = NULL, *cdel = NULL;
char edbuf [6 + 2 * WIDTH], cmdbuf [4 + TWID], schbuf [4 + TWID],
*mark = "<<< - MARK - >>>", *endz = edbuf + WIDTH, *scename;
int xcur, ycur, tcur, dircc, bfull = 0, rfull = 0, clrct = 0,
eflag = 0, iflag = 1, pflag = 0, cflag = 0, tflag = 0;
/* Main - initialise for edit */
main (argc, argv) int argc; char *argv[];
{ static int e;
/* Reassign MSDOS stdin and stdout */
if ((e = open ("CON", 2)) != -1)
{ reopen (_fdsin, e); reopen (_fdsout, e); }
/* Initialise edit buffer pointers */
cls (1); nalloc (0);
bfs->lptr = bfs; bfs->rptr = bfe;
bfe->lptr = bfs; bfe->rptr = bfe;
scename = (argc > 1) ? *++argv : "WORK";
cmdloop(); cls (1); } /* End of main */
/* Edit and command loop */
cmdloop()
{ static int sce, c, k; static char *s;
static mtag *p, *q, *r;
/* Read the source file */
sce = bopen (0, scename); setscr();
xcur = 1; ycur = TOPROW; scrloc();
if (sce != NULL) rdfile (&sce, bfe);
else { toptxt ("New file."); bell(); }
sline = bfs->rptr;
while (1)
{ keyedit();
if (match (cmdbuf, "more"))
{ if (!sce) toptxt ("None left.");
else rdfile (&sce, bfe); continue; }
if (k = match (cmdbuf, "insert"))
{ s = cmdbuf + k;
if ((k = bopen (1, (*s) ? s : EXFILE)) == NULL)
{ toptxt ("Cannot open."); continue; }
cset(); q = curline();
if (q == bfe) q = bufins ("\0", bfe);
rdfile (&k, q->rptr);
redis (q); continue; }
if ((k = match (cmdbuf, "store")) ||
(k = match (cmdbuf, "extract")))
{ if (mline == NULL) { toptxt ("No mark."); continue; }
if ((q = curline()) == mline || q->rptr == mline)
{ toptxt ("Nothing to save."); continue; }
s = cmdbuf + k; s += (k = match (s, "\\s"));
r = bfs->rptr; while (r != q && r != mline) r = r->rptr;
if (fsave ((*s) ? s : EXFILE, r->rptr,
r == q ? mline : q->rptr, k) == 0) topclr();
if (match (cmdbuf, "extract") && qcheck()) return;
continue; }
if (match (cmdbuf, "delete"))
{ if (mline == NULL) { toptxt ("No mark."); continue; }
cset(); pflag = 0; q = curline();
r = bfs->rptr; while (r != q && r != mline) r = r->rptr;
if (r == mline) { p = q->rptr; q = r->lptr; }
else { r = r->rptr; p = mline->rptr; }
while (r != p)
{ r->lptr->rptr = r->rptr;
r->rptr->lptr = r->lptr;
nfree (r); r = r->rptr; }
mline = 0; redis (q); nprin(); continue; }
if (match (cmdbuf, "quit"))
{ if (qcheck()) return;
continue; }
if (k = match (cmdbuf, "end"))
{ s = cmdbuf + k; s += (k = match (s, "\\s"));
if (!cflag && !*s) return;
if (sce != NULL) { toptxt ("Source unfinished."); continue; }
if (fsave ((*s) ? s : scename, bfs->rptr,
bfe, k) == -1) continue;
return; }
/* Unknown command */
cls (1); dirloc (1, 1); putstr (cmdbuf);
putstr (" >\n"); system (cmdbuf);
putstr ("\nPress any key to return to Edit: ");
getch(); cls (0); continue;
} } /* End of cmdloop */
/* Check for quit */
qcheck()
{ static char c;
if (!cflag) return 1;
toptxt ("Confirm QUIT (Y/N): ");
c = getch(); topclr();
return (c == 'y' || c == 'Y'); }
/* Match a command */
match (b, t) char *b, *t;
{ static int c; static char *s; s = b;
while (*s == ' ') ++s;
while (*t)
{ if ((c = *s) >= 'A' && c <= 'Z') c += 0x20;
if (c != *t) return 0; ++s; ++t; }
if (*s && *s != ' ') return 0;
while (*s == ' ') ++s;
return s - b; }
/* Key-stroke edit functions - xcur, ycur and sline set on entry;
performs all single-key edit functions; command buf set on exit */
keyedit()
{ static int c, f, i, k, v;
static mtag *q, *r;
static char *s, *t, *u;
setscr(); raster (TOPROW); nprin();
while (1)
{ c = getch(); if (clrct && !--clrct) topclr();
/* Normal character entry */
if (c >= 0x20 && c <= 0x7E)
{ if (tflag) { if (tcur >= TWID) bell();
else { edbuf [tcur++] = c; topdis(); }
continue; }
if (curline() == mline) { bell(); continue; }
if (testful (0)) continue;
edset(); v = 0; f = setzz (&s, xcur, 1);
if (!f && iflag)
{ setrc (&t, s); *t = 0;
if (t >= endz)
{ t = endz; *--t = 0; v = 1; }
do *(t+1) = *t; while (--t >= s); }
*s = c; if (f) *(s+1) = 0;
dirloc (xcur, ycur); dirstr (s);
if (xcur < WIDTH) ++xcur; else v = 1;
if (v) bell(); scrloc(); continue; }
switch (c) /* Topline entry actions */
{ case KTOP: /* top of file */
edcheck(); undel(); xcur = 1; ycur = TOPROW;
sline = bfs->rptr; raster (TOPROW); break;
case KEOF: /* end of file */
sline = bfe; xcur = 1; ycur = ENDROW;
/* Continue as up screen */
case KSCUP: /* up screen */
edcheck(); undel();
for (i = TOPROW; i < ENDROW; i++)
if (sline->lptr != bfs) sline = sline->lptr;
raster (TOPROW); break;
case KSCDN: /* down screen */
edcheck(); undel();
for (q = sline, i = TOPROW;
i < ENDROW; i++) q = q->rptr;
sline = (q == bfe) ? sline : q;
raster (TOPROW); break;
case KCLF: /* left cursor */
if (xcur > 1) --xcur; scrloc(); break;
case KCRT: /* right cursor */
if (xcur < WIDTH) ++xcur; scrloc(); break;
case KCDN: /* down cursor */
dncurs(); break;
case KCUP: /* up cursor */
edcheck(); undel();
if (ycur > TOPROW) --ycur;
else if (sline != bfs->rptr)
{ dirlins (TOPROW); dirloc(1, TOPROW);
dirstr ((sline = sline->lptr) + 1); }
scrloc(); break;
case KESC: /* find/replace or end of line */
if (tflag) { edbuf [tcur++] = RCHAR;
topdis(); break; }
/* Continue as end of line */
case KCEOL: /* Cursor end of line */
edcheck(); q = curline();
for (i = 1, t = q + 1; *t; ++t)
i += (*t < 0x20) ? *t : 1;
xcur = i; scrloc(); break;
case KLDEL: /* <-delete */
if (tflag) { if (tcur > 1)
{ --tcur; topdis(); } break; }
if (curline() == mline) { bell(); break; }
if (xcur == 1) break;
--xcur; scrloc(); /* Continue as delete-> */
case KRDEL: /* delete-> */
if (tflag) break;
if ((q = curline()) == bfe) break;
if (q == mline) { bell(); break; }
edset(); f = setzz (&s, xcur, 0);
if (!f) { t = s+1; while (*(t-1) = *t) ++t;
dirloc (xcur, ycur);
dirstr (s); direol(); }
scrloc(); break;
case KTAB: /* Tab - ignores insert */
xcur += (TABS - (xcur - 1) % TABS);
if (xcur >= WIDTH) xcur = WIDTH; scrloc(); break;
case KINS: /* insert toggle */
dirloc (WIDTH - 9, 1); dirstr (iflag ? " " : "I");
iflag ^= 0x01; break;
case KQAC: /* Q cursor action */
edcheck(); undel();
if (xcur != 1) xcur = 1;
else if (ycur != TOPROW) ycur = TOPROW;
else for (q = sline, ycur = TOPROW; ycur < ENDROW;
q = q->rptr, ++ycur) if (q == bfe) break;
scrloc(); break;
case KF3: /* Break line */
if (tflag) break;
if (curline() == bfe) break;
if (!testful (0))
{ if (!eflag && xcur == 1)
{ cset(); q = bufins ("\0", curline());
if (ycur == TOPROW) sline = q;
dirlins (ycur); }
else
{ if (curline() == mline) { bell(); break; }
edset(); f = setzz (&s, xcur, 0);
if (!f || eline->rptr != bfe)
bufins (f ? "\0" : s, eline->rptr);
*s = 0; dirloc (xcur, ycur); direol();
if (ycur < ENDROW)
{ dirlins (1 + ycur); dirloc (1, 1 + ycur);
dirstr (eline->rptr + 1); } } }
xcur = 1; dncurs(); break;
case KRET: /* Ret */
if (tflag) { topclr(); edbuf [tcur] = 0;
strcpy (cmdbuf, edbuf + 1);
tflag = 0; return; }
if (!testful (0))
{ if (iflag)
{ cset(); q = curline();
r = bufins ("\0", q->rptr);
if (q == bfe) q = r;
if (ycur < ENDROW) dirlins (1 + ycur); }
else { if ((q = curline()) == bfe)
{ cset(); q = bufins ("\0", bfe); } }
if (sline == bfe) sline = q; }
/* Continue as KF6 */
case KF6: /* CR LF */
xcur = 1; dncurs(); break;
case KGOMK: /* Go to mark */
if (mline == NULL) break;
edcheck(); undel();
redis (mline); raster (TOPROW); break;
case KSRCH: /* Search/replace string */
if (tflag) { topclr(); edbuf [tcur] = 0;
strcpy (schbuf, edbuf + 1); tflag = 0; }
else edcheck(); undel();
if ((q = curline()) == bfe)
{ toptxt ("Cannot find."); break; }
if (*schbuf == RCHAR || *schbuf == 0)
{ toptxt ("No search string."); break; }
v = 0; unpack (q + 1, edbuf);
if (!setzz (&s, xcur + 1, 0))
{ if ((k = sfind (s, schbuf)) >= 0)
{ xcur += (k + 1); v = 1; } }
if (!v)
{ toptxt (schbuf);
while ((q = q->rptr) != bfe)
{ unpack (q + 1, edbuf);
if ((k = sfind (edbuf, schbuf)) >= 0)
{ xcur = (k + 1); redis (q);
v = 1; break; } } }
if (v) topclr(); else { toptxt ("Cannot find."); break; }
v = 0; for (s = schbuf; *s; ++s) if (*s == RCHAR) break;
if (*s && q != mline)
{ k = s++ - schbuf; edset();
t = edbuf + (xcur - 1);
strcpy (u = t + k + WIDTH + 2, t + k);
while (*s && *s != RCHAR) *t++ = *s++;
while (*u) *t++ = *u++;
if (t > endz) { t = endz; v = 1; }
*t = 0; edcheck(); }
raster (TOPROW); if (v) bell(); break;
case KRFSH: /* Refresh screen */
edcheck(); raster (TOPROW); break;
case KTLIN: /* command entry */
topclr();
if (tflag ^= 0x1)
{ edcheck(); tcur = 1;
edbuf [0] = '>'; topdis(); }
break;
case KSAVE: case KQUIT:
edcheck();
strcpy (cmdbuf, c == KQUIT ? "quit" : "end");
return;
} /* End of topline switch */
if (tflag) continue;
switch (c) /* Non-topline actions */
{ case KDEOL: /* Delete to end of line */
if ((q = curline()) == bfe) break;
if (q == mline) { bell(); break; }
edset(); t = edbuf + (xcur - 1); *t = 0;
dirloc (xcur, ycur); direol(); break;
case KCONC: /* concatenate lines */
cset(); edcheck(); undel();
if (testful (0) || xcur >= WIDTH ||
(q = curline()) == bfe) break;
if (q == mline || q->rptr == mline) { bell(); break; }
if (q->rptr != bfe)
{ edset(); f = setzz (&s, xcur, 1);
if (!f) setrc (&t, s); else t = s;
q = eline->rptr; unpack (q + 1, t);
eline->rptr = q->rptr; q->rptr->lptr = eline;
if (q != bfe) nfree (q);
f = setzz (&s, WIDTH + 1, 0);
if (!f) { setrc (&t, s); *t = 0;
do *(t+2) = *t; while (--t >= s);
bufins (s + 2, eline->rptr); }
*s = 0; edcheck(); }
else if (xcur == 1 && *(char *)(q + 1) == 0)
{ q->lptr->rptr = bfe; bfe->lptr = q->lptr;
if (sline == q) sline = bfe; nfree (q); }
raster (ycur); break;
case KBDEL: /* line delete and store */
cset(); edcheck(); q = curline(); pflag = 0;
if (sdel == NULL)
sdel = cdel = (q == mline) ? NULL : q;
else if (q != cdel->rptr)
{ r = sdel->rptr;
while (sdel != cdel)
{ nfree (sdel); sdel = r;
r = r->rptr; }
sdel = cdel = (q == mline) ? NULL : q; }
else if (q != bfe)
{ if (q == mline) cdel->rptr = q->rptr;
else cdel = q; }
if (sdel == bfe)
{ sdel = cdel = NULL; nprin(); break; }
q->lptr->rptr = q->rptr;
q->rptr->lptr = q->lptr;
if (q == mline) { nfree (mline); mline = NULL; }
if (q == sline) sline = q->rptr;
dirldel (ycur); q = sline;
for (i = TOPROW; i < ENDROW; ++i) q = q->rptr;
dirloc (1, ENDROW); dirstr (q + 1);
nprin(); break;
case KBRES: /* buffer restore */
cset(); edcheck(); undel();
if (sdel == NULL || testful (0)) break;
pflag = 0;
if ((q = curline()) == bfe)
q = bufins ("\0", bfe);
if (sline == bfe) sline = q;
for (r = sdel; ; r = r->rptr)
{ if (testful (0)) break;
unpack (r + 1, edbuf);
q = bufins (edbuf, q->rptr);
if (r == cdel) break; }
nprin(); raster (ycur); break;
case KMARK: /* Set mark */
edcheck(); undel(); q = curline();
q = bufins (mark, q->rptr);
if (mline != NULL)
{ mline->lptr->rptr = mline->rptr;
mline->rptr->lptr = mline->lptr;
nfree (mline); }
sline = mline = q;
if (ycur < ENDROW) ++ycur;
for (i = TOPROW; i < ycur; i++)
sline = sline->lptr;
if (sline == bfs)
{ sline = bfs->rptr; --ycur; }
raster (TOPROW); break;
case KTWRD:
if ((q = curline()) == bfe) break;
edcheck(); f = 0; q = curline();
for (i = 1, t = q + 1; *t; ++t)
i += (*t < 0x20) ? *t : 1;
if (xcur >= i)
{ xcur = f = 1; dncurs();
if ((q = curline()) == bfe) break; }
unpack (q + 1, edbuf); t = edbuf + (xcur - 1);
if (!f) while (isalnum (*t)) { ++t; ++xcur; }
while (*t && !isalnum (*t)) { ++t; ++xcur; }
scrloc(); break;
} } /* End of edit switch */
} /* End of keyedit */
/* Cmdloop and keyedit support routines */
/* Set pointer to x in edbuf; return 1 if beyond eol */
setzz (s, x, f) char **s;
{ static int v; static char *t;
*s = edbuf + (x - 1);
for (v = 0, t = edbuf; t <= *s; t++)
{ if (*t == 0) v = 1;
if (f && v) *t = ' '; }
return v; }
/* Set after last non-blank char */
setrc (t, e) char **t, *e;
{ *t = e; while (**t) ++*t;
while (*t > e && *(*t-1) == ' ') --*t; }
/* Get cursor line */
curline()
{ static int i; static mtag *p;
for (p = sline, i = TOPROW;
i < ycur; i++) p = p->rptr;
return p; }
/* Cursor down one line */
dncurs()
{ static mtag *q;
edcheck(); undel();
if ((q = curline()) == bfe) return;
if (ycur < ENDROW) ++ycur;
else { dirldel (TOPROW); dirloc (1, ENDROW);
dirstr (q->rptr + 1); sline = sline->rptr; }
scrloc(); }
/* Unlink deleted lines buffer */
undel() { if (cdel) cdel->rptr = 0; }
/* Set change flag */
cset() { cflag = 1; }
/* Find string t within buffer b */
sfind (b, t) char *b, *t;
{ static char *s, *x; s = b; x = t;
/* for (s = b; *s; ++s)
{ for (v = 1, x = s, y = t;
(*y && *y != RCHAR); ++x, ++y)
if (*x != *y) { v = 0; break; }
if (v) return s - b; }
return -1; } */
inline ( 0x8B, 0x36, &s, 0x8B, 0x16, &x, 0x8A, 0x04,
0x08, 0xC0, 0x74, 0x19, 0x89, 0xF3, 0x89, 0xD7,
0x8A, 0x05, 0x08, 0xC0, 0x74, 0x11, 0x3C, RCHAR,
0x74, 0x0D, 0x3A, 0x07, 0x75, 0x04, 0x43, 0x47,
0xEB, 0xEE, 0x46, 0xEB, 0xE1, 0x31, 0xF6,
0x89, 0x36, &s );
return s ? s - b : -1; }
/* Line edit buffer handling routines */
/* Unpack cursor line to the edit buffer */
edset()
{ static int i; static char *t, *x;
cset(); if (eflag) return; eflag = 1;
if ((eline = curline()) == bfe)
eline = bufins ("\0", bfe);
if (sline == bfe) sline = eline;
unpack (eline + 1, edbuf); }
/* Reload edited line to buffer */
edcheck()
{ static mtag *q;
if (!eflag) return; eflag = 0;
q = bufins (edbuf, eline->rptr);
eline->lptr->rptr = eline->rptr;
eline->rptr->lptr = eline->lptr;
if (sline == eline) sline = q;
nfree (eline); }
/* Insert string s next before buffer line p -
exits on overflow or returns pointer to inserted line */
bufins (s, p) char *s; mtag *p;
{ static mtag *q; static int n;
static char *t, *x;
n = pack (s, endz + 2);
if ((q = nalloc (n + 1)) == NULL)
{ cls (1); putstr ("\nEdit aborted - buffer overflow.\n");
_exit (0xFF); }
strcpy (q + 1, endz + 2);
q->lptr = p->lptr; q->rptr = p;
return p->lptr = p->lptr->rptr = q; }
/* Pack line */
pack (s, d) char *s, *d;
{ static int c, f; static char *t, *e; t = s; e = d;
/* f = 0; while (1)
{ if ((c = *s++) == 0) { if (f) *d++ = f; *d = 0; break; }
else if (c > 0x20) { if (f) *d++ = f; f = 0; *d++ = c; }
else if (++f == 0x1F) {*d++ = f; f = 0; } } return d - e; } */
inline ( 0x8B, 0x36, &t, 0x8B, 0x3E, &e, 0x30, 0xC9,
0x8A, 0x04, 0x46, 0x3C, 0x20, 0x74, 0x10, 0x72, 0x1C,
0x08, 0xC9, 0x74, 0x05, 0x88, 0x0D, 0x47, 0x30, 0xC9,
0x88, 0x05, 0x47, 0xEB, 0xE9,
0xFE, 0xC1, 0x80, 0xF9, 0x1F, 0x72, 0xE2,
0x88, 0x0D, 0x47, 0x30, 0xC9, 0xEB, 0xDB,
0x08, 0xC9, 0x74, 0x05, 0x88, 0x0D, 0x47, 0x30, 0xC9,
0xC6, 0x05, 0x00, 0x89, 0x3E, &e );
return e - d; }
/* Unpack line for spaced output */
unpack (s, d) char *s, *d;
{ static int c; static char *t, *e; t = s; e = d;
/* while (1)
{ if ((c = *s++) == 0) { *d = 0; break; }
else if (c > 0x20) *d++ = c;
else while (c--) *d++ = 0x20; } return d - e; } */
inline ( 0x8B, 0x36, &t, 0x8B, 0x3E, &e,
0x8A, 0x04, 0x46, 0x08, 0xC0, 0x74, 0x13,
0x3C, 0x20, 0x72, 0x05,
0x88, 0x05, 0x47, 0xEB, 0xF0,
0xC6, 0x05, 0x20, 0x47, 0xFE, 0xC8,
0x75, 0xF8, 0xEB, 0xE6,
0x88, 0x05, 0x89, 0x3E, &e );
return e - d; }
/* Unpack line for tabbed output */
untpak (s, d) char *s, *d;
{ static char *e, *p; e = d; p = s;
/* while (1)
{ while ((c = *p) && c > 0x20)
{ *d++ = c; ++p; ++k; } t1 = k;
while ((c = *p) && c <= 0x20)
{ k += (c == 0x20) ? 1 : c; ++p; }
if (!c) break; t2 = k / 8;
for (i = t1 / 8; i < t2; ++i) *d++ = '\t';
t2 *= 8; t1 = (t2 > t1) ? t2 : t1;
for (i = t1; i < k; ++i) *d++ = ' '; } */
inline ( 0x8B, 0x1E, &p, 0x8B, 0x3E, &e, 0x31, 0xC9,
0x31, 0xC0, 0x8A, 0x07, 0x08, 0xC0, 0x74, 0x0B,
0x3C, 0x21, 0x72, 0x07, 0x88, 0x05, 0x43, 0x47, 0x41,
0xEB, 0xED, 0x89, 0xCA, 0x8A, 0x07, 0x08, 0xC0,
0x74, 0x0F, 0x3C, 0x21, 0x73, 0x0B, 0x3C, 0x20,
0x75, 0x02, 0xB0, 0x01, 0x01, 0xC1, 0x43,
0xEB, 0xEB, 0x08, 0xC0, 0x74, 0x2B,
0x89, 0xD0, 0x25, 0xF8, 0xFF, 0x89, 0xCE,
0x81, 0xE6, 0xF8, 0xFF, 0x39, 0xF0, 0x73, 0x09,
0xC6, 0x05, 0x09, 0x47, 0x05, 0x08, 0x00, 0xEB, 0xF3,
0x39, 0xD0, 0x72, 0x02, 0x89, 0xC2, 0x39, 0xCA,
0x73, 0x07, 0xC6, 0x05, 0x20, 0x47, 0x42, 0xEB, 0xF5,
0xEB, 0xA7, 0x89, 0x3E, &e );
return e - d; }
/* Edit buffer handling - all pointers are to the mtag header */
/* Allocate a new buffer line */
nalloc (nb) unsigned nb;
{ static mtag *p, *q; static unsigned nt;
if (!last) /* reserve entire heap */
{ base.lptr = last = &base; base.size = 0;
p = * (mtag **) 0x100; q = * (mtag **) 0x102;
nt = q - p; p->size = nt - 2; nfree (p); }
nt = 1 + (nb + (sizeof (mtag) - 1)) / sizeof (mtag);
for (q = last, p = q->lptr; ; q = p, p = p->lptr)
{ if (p->size >= nt)
{ if (p->size != nt)
{ p->size -= nt; p += p->size; p->size = nt; }
else q->lptr = p->lptr;
last = q; testful (1); return p; }
if (p == last) return NULL; }
} /* End */
/* Free memory line */
nfree(b) mtag *b;
{ static mtag *p, *q; p = b;
for (q = last; ; q = q->lptr)
if ((q < p && q->lptr > p) ||
(q->lptr <= q &&
(p > q || p < q->lptr) )) break;
if (p + p->size != q->lptr) p->lptr = q->lptr;
else { p->size += q->lptr->size; p->lptr = q->lptr->lptr; }
if (q + q->size != p) q->lptr = p;
else { q->size += p->size; q->lptr = p->lptr; }
last = q; testful (1); }
/* Set to print buffer size */
nprin() { pflag = 1; testful (1); }
/* Test/set edit buffer full */
testful (f)
{ static mtag *p, *q; static unsigned i, j, lb, nt =
1 + (WIDTH + 4 + (sizeof (mtag) - 1)) / sizeof (mtag);
if (!f && !bfull) return 0;
i = j = 0; lb = bfull; p = last;
do { i += (p->size / nt);
j += (p->size - 1);
p = p->lptr; } while (p != last);
rfull = (i < 30);
if (lb ^ (bfull = (i < 4)))
{ dirloc (30, 1);
dirstr (bfull ? "Full!" : " "); }
if (pflag) { dirloc (WIDTH - 5, 1);
dirdec (j * sizeof (mtag)); }
if (!f && bfull) bell();
return bfull; }
/* File input/output */
/* Set file buffer and open file */
bopen (i, s) char *s;
{ static int fd; static qbuf bb[2], *b;
if ((fd = open (s, 0)) == -1) return NULL;
b = bb + i; b->qfd = fd; b->qnd = 0; return b; }
/* Read file to buffer full */
rdfile (fp, p) int *fp; mtag *p;
{ pflag = 0;
while (!rfull)
{ inscline (fp);
if (!*fp && *edbuf == 0) break;
bufins (edbuf, p); }
if (rfull) toptxt ("File unfinished.");
nprin(); }
/* Raw line input to edbuf - returns
*f = 0 and *edbuf = 0 at EOF */
inscline (f) qbuf **f;
{ static n, k, tbc; static char *s;
static qbuf *b;
s = edbuf; *s = 0; tbc = 1;
if (!(b = *f)) return;
while (1)
{ if (s >= endz) { k = 0; break; }
if (b->qnx >= b->qnd)
{ if ((n = read (b->qfd, b->qbb, QBSIZE)) > 0)
b->qnd = (b->qnx = b->qbb) + n;
else { k = EOF; break; } }
/* k = *(b->qnx)++; */ &b->qnx;
inline ( 0x8B, 0x3F, 0x47, 0x89, 0x3F, 0x4F,
0x8A, 0x1D, 0xB7, 0x00, 0x89, 0x1E, &k );
if ( k == '\r' ) continue;
if ( k == '\n' ) break;
if ( k == '\t' )
/* do { ++tbc; if (s < endz) *s++ = ' '; }
while ( tbc % 8 != 1 ); */
inline ( 0xBE, &tbc, 0xBB, &s, 0x8B, 0x16, &endz,
0xFF, 0x04, 0x8B, 0x3F, 0x39, 0xD7, 0x73, 0x05,
0xC6, 0x05, 0x20, 0xFF, 0x07, 0x8B, 0x04,
0x25, 0x07, 0x00, 0x3D, 0x01, 0x00, 0x75, 0xE9 );
else
/* { ++tbc; k &= 0x7F;
*s++ = k + (k < 0x20 ? 0x40 : 0); } */
inline ( 0xBB, &tbc, 0xFF, 0x07, 0xBB, &s,
0xA1, &k, 0x24, 0x7F, 0x3C, 0x20,
0x73, 0x02, 0x04, 0x40, 0x8B, 0x3F,
0x88, 0x05, 0x47, 0x89, 0x3F );
}
*s = 0; if (k < 0) { close ((*f)->qfd); *f = 0; }
} /* End of inscline */
/* Save buffer lines s - t to file nm */
fsave (nm, s, t, z) char *nm; mtag *s, *t;
{ static int e, f, v; static mtag *q;
int unpack(), untpak(), (*up)();
up = z ? unpack : untpak;
if ((f = creat (nm, 0)) == -1)
{ toptxt ("Cannot open "); dirstr (nm); return -1; }
toptxt ("Saving: "); dirstr (nm);
for (v = 0, q = s; q != t; q = q->rptr)
{ if (q == mline) continue;
e = (*up) (q + 1, edbuf);
edbuf [e++] = 0x0D; edbuf [e++] = 0x0A;
if (write (f, edbuf, e) != e)
{ toptxt ("Write error."); v = -1; break; } }
if (close (f) == -1)
{ toptxt ("Cannot close "); dirstr (nm); return -1; }
return v; }
/* Edit screen display routines */
/* Print screen header layout */
setscr()
{ static int i;
dirloc (WIDTH - 29, 1); dirstr ("File: "); dirstr (scename);
dirloc (WIDTH - 9, 1); dirstr (iflag ? "I" : " ");
for (dirloc (1, 2), i = 1; i <= WIDTH; i++)
dirstr (i % TABS == 1 ? "+" : "-"); }
/* Display edit raster from line n */
raster (n)
{ static int i, j; static mtag *q;
for (q = sline, i = TOPROW; i <= ENDROW; q = q->rptr, ++i)
{ if (q == bfe && ycur > i) ycur = i;
if (i >= n) { dirloc (1, i); dirstr (q + 1); direol(); }
for (j = 0; j < 80; j++); /* DELAY */ }
scrloc(); }
/* Reset with edit line p at screen line ycur */
redis (p) mtag *p;
{ static int i; static mtag *q;
for (q = p, i = TOPROW; i < ycur; i++) q = q->lptr;
if ((sline = q) == bfs)
for (q = sline = bfs->rptr, ycur = TOPROW;
q != p; q = q->rptr) ++ycur; }
/* Topline display routines */
topclr() { static int i, k = 1 + TWID / 4;
dirloc (i = 1, 1); while (i++ <= k) dirstr (" "); }
topdis() { strcpy (edbuf + tcur, "_ ");
dirloc (1, 1); dirstr (edbuf); }
toptxt(s) char *s;
{ topclr(); dirloc (1, 1);
dirstr (s); clrct = TCLR; }
/* Video and console output routines */
/* Clear screen, home cursor */
cls (f) { static int i, xd, yd;
xd = xcur; yd = ycur;
if (f) xcur = ycur = 1; scrloc();
xcur = xd; ycur = yd;
for (i = 1; i <= ENDROW; i++)
{ dirloc (1, i); direol(); } }
/* Move cursor to xcur, ycur (ANSI.SYS output) */
scrloc()
{ static char ss[] = "\33[00;00H";
ss[2] = dig (ycur / 10); ss[3] = dig (ycur % 10);
ss[5] = dig (xcur / 10); ss[6] = dig (xcur % 10);
putstr (ss); }
dig (n) { return '0' + n + (n > 9 ? 7 : 0); }
/* Ring the bell */
bell() { putstr ("\7"); }
/* Keyboard entry - wait for next character */
getch()
{ static int c;
while (!(c = rawin())); return c; }
/* Put string to stdout - Bdos fn 6 to avoid Control-C */
putstr (s) char *s;
{ static char *t; t = s;
inline ( 0x8B, 0x3E, &t, 0x31, 0xDB,
0x8A, 0x05, 0x47, 0x08, 0xC0, 0x75, 0x01,
0xC3, 0x43, 0x3C, 0x0A, 0x74, 0x08, 0x88,
0xC2, 0xB4, 0x06, 0xCD, 0x21, 0xEB, 0xEB,
0xB2, 0x0D, 0xB4, 0x06, 0xCD, 0x21,
0xB2, 0x0A, 0xB4, 0x06, 0xCD, 0x21, 0xEB, 0xDD ); }
/* Output decimal unsigned value v */
dirdec (v) unsigned v;
{ static char b[] = " ", *s;
s = b + 5; ppd (v, &s); *s = 0; dirstr (s - 5); }
ppd (n, p) unsigned n; char **p;
{ if (n < 10) { *(*p)++ = '0' + n +
(n > 9 ? 7 : 0); return; }
ppd (n / 10, p); ppd (n % 10, p); }
/* Direct output to screen memory at B800:0 */
/* Set direct output cursor */
dirloc(x, y) int x, y; { dircc = x + x + y * 0xA0 - 0xA2; }
/* Output packed or normal strings */
dirstr (s) char *s;
{ static char *ss; ss = s;
inline ( 0x8B, 0x1E, &ss, 0x8B, 0x3E, &dircc,
0x06, 0xB8, 0x00, 0xB8, 0x8E, 0xC0, 0x8A, 0x07,
0x43, 0x3C, 0x20, 0x72, 0x07, 0x26, 0x88, 0x05,
0x47, 0x47, 0xEB, 0xF2, 0x08, 0xC0, 0x74, 0x0C,
0x26, 0xC6, 0x05, 0x20, 0x47, 0x47, 0xFE, 0xC8,
0x75, 0xF6, 0xEB, 0xE2, 0x07, 0x89, 0x3E, &dircc ); }
/* Erase to end of line */
direol()
{ static unsigned nb; nb = (0xA0 - (dircc % 0xA0)) >> 1;
inline ( 0x8B, 0x3E, &dircc,0x8B, 0x0E, &nb,
0x06, 0xB8, 0x00, 0xB8, 0x8E, 0xC0, 0x26, 0xC6,
0x05, 0x00, 0x47, 0x47, 0xE2, 0xF8, 0x07 ); }
/* Insert cleared line n */
dirlins (n)
{ static int dd, nb;
if ( n < ENDROW )
{ nb = (ENDROW - n) * 0x50;
inline ( 0xBE, (ENDROW-1) * 0xA0 - 2, 0xBF, ENDROW * 0xA0 - 2,
0x8B, 0x0E, &nb, 0x06, 0xB8, 0x00, 0xB8,
0x8E, 0xC0, 0x26, 0x8A, 0x04, 0x26, 0x88, 0x05,
0x4E, 0x4E, 0x4F, 0x4F, 0xE2, 0xF4, 0x07 ); }
dd = dircc; dirloc (1, n); direol(); dircc = dd; }
/* Delete line n and clear last line */
dirldel (n)
{ static int dd, ns, nd, nb;
if ( n < ENDROW )
{ ns = n * 0xA0; nd = ns - 0xA0; nb = (ENDROW - n) * 0x50;
inline ( 0x8B, 0x36, &ns, 0x8B, 0x3E, &nd,
0x8B, 0x0E, &nb, 0x06, 0xB8, 0x00, 0xB8, 0x8E,
0xC0, 0x26, 0x8A, 0x04, 0x26, 0x88, 0x05,
0x46, 0x46, 0x47, 0x47, 0xE2, 0xF4, 0x07 ); }
dd = dircc; dirloc (1, ENDROW); direol(); dircc = dd; }
/* End of Editor */
#include ?smio.lib?